package org.example

import com.alibaba.druid.pool.DruidDataSource
import com.baomidou.mybatisplus.MybatisConfiguration
import com.baomidou.mybatisplus.entity.GlobalConfiguration
import com.baomidou.mybatisplus.mapper.LogicSqlInjector
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor
import com.baomidou.mybatisplus.plugins.Page
import com.baomidou.mybatisplus.plugins.PaginationInterceptor
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
import com.wix.mysql.EmbeddedMysql
import com.wix.mysql.config.MysqldConfig
import org.apache.ibatis.plugin.Interceptor
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.mybatis.spring.mapper.MapperScannerConfigurer
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.Resource

import static com.wix.mysql.EmbeddedMysql.anEmbeddedMysql
import static com.wix.mysql.ScriptResolver.classPathScript
import static com.wix.mysql.ScriptResolver.classPathScripts
import static com.wix.mysql.config.Charset.UTF8
import static com.wix.mysql.config.MysqldConfig.aMysqldConfig
import static com.wix.mysql.distribution.Version.v5_7_latest
import static org.hamcrest.core.Is.is
import static org.junit.Assert.assertThat
import static org.junit.Assert.assertTrue
import static org.junit.Assert.assertFalse

class MyBatisPlusDemoTests {

    private EmbeddedMysql mysqld

    private MapperScannerConfigurer mapperScannerConfigurer

    @Before
    void setup() {
        //init embedded mysql
        MysqldConfig config = aMysqldConfig(v5_7_latest)
                .withCharset(UTF8)
                .withPort(2215)
                .withUser("user", "password")
                .build()

        mysqld = anEmbeddedMysql(config)
                .addSchema("schema1", classPathScript("db/001_init.sql"))
                .addSchema("schema2", classPathScripts("db/*.sql"))
                .start()

        //init druid
        def dataSource = new DruidDataSource()
        dataSource.setUrl("jdbc:mysql://localhost:2215/schema2")
        dataSource.setUsername("user")
        dataSource.setPassword("password")

        //init mybatis-plus
        mapperScannerConfigurer = new MapperScannerConfigurer(
                basePackage: "org.example",
                sqlSessionFactory: new MybatisSqlSessionFactoryBean(
                        dataSource: dataSource,
                        typeAliasesPackage: "org.example",
                        configuration: new MybatisConfiguration(),
                        globalConfig: new GlobalConfiguration(sqlInjector: new LogicSqlInjector(), logicDeleteValue: "-1", logicNotDeleteValue: "1", idType: "2"),
                        mapperLocations: [
                                new ClassPathResource("org/example/T5Mapper.xml"),
                                new ClassPathResource("org/example/T4Mapper.xml"),
                                new ClassPathResource("org/example/T3Mapper.xml"),
                                new ClassPathResource("org/example/T2Mapper.xml")
                        ] as Resource[],
                        plugins: [
                                new PaginationInterceptor(),
                                new OptimisticLockerInterceptor()
                        ] as Interceptor[]
                ).getObject()
        )
    }

    @After
    void cleanup() {
        mysqld.stop() //optional, as there is a shutdown hook
    }

    @Test
    void ensureLogicDeleteIsWorking() {
        final selectCount = "select count(*) from t5"
        assertTrue(new T5(col1: 1).insert())
        assertThat(new T5().sql().selectCount(selectCount, null), is(1))
        assertTrue(new T5().deleteById(1))
        assertThat(new T5().sql().selectCount(selectCount, null), is(1))
    }

    @Test
    void ensureActiveRecordIsWorking() {
        assertThat(new T2(field1: 1, field2: "first t2").insert(), is(true))
        assertThat(new T2().selectById(1).field2, is("first t2"))
        assertThat(new T2(field1: 1, field2: "modify t2").updateById(), is(true))
        assertThat(new T2().selectById(1).field2, is("modify t2"))
        assertThat(new T2().delete(null), is(true))
        assertThat(new T2().selectAll().size(), is(0))
    }

    @Test
    void ensurePaginationIsWorking() {
        Page<T2> page = new T2().selectPage(new Page<T2>(1, 2), null)
        assertThat(page.getRecords().size(), is(page.size))
        assertTrue(page.hasNext())
        assertTrue(!page.hasPrevious())
        assertThat(new T2().selectAll().size().toLong(), is(page.total))

        def t3mapper = mapperScannerConfigurer.sqlSessionFactory.openSession().getMapper(T3Mapper.class)
        def page2 = new Page(2, 2)
        def pageList2nd = t3mapper.mySelect(page2)
        assertThat(pageList2nd.first().col1, is(7))
        assertThat(pageList2nd.last().col1, is(6))
        assertThat(page2.total, is(9L))
    }

    @Test
    void ensureOptimisticLockerIsWorking() {
        def first = new T4().selectById(1)

        def second = new T4().selectById(1)

        second.col2 = "我好！"
        assertTrue(second.updateById())

        first.col2 = '大家好！'
        assertFalse(first.updateById())
    }
}
